home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Tcl_Fork C Library Procedures Tcl_Fork
-
-
-
- _________________________________________________________________
-
- NNAAMMEE |
- Tcl_Fork, Tcl_WaitPids, Tcl_DetachPids - manage child |
- processes |
-
- SSYYNNOOPPSSIISS |
- ##iinncclluuddee <<ttccll..hh>> |
-
- int |
- TTccll__FFoorrkk( ) |
-
- int |
- TTccll__WWaaiittPPiiddss(_n_u_m_P_i_d_s, _p_i_d_P_t_r, _s_t_a_t_u_s_P_t_r) |
-
- int |
- TTccll__DDeettaacchhPPiiddss(_n_u_m_P_i_d_s, _p_i_d_P_t_r) |
-
- AARRGGUUMMEENNTTSS |
- int _n_u_m_P_i_d_s (in) ||
- Number of process ids contained |
- in the array pointed to by |
- _p_i_d_P_t_r. |
-
- int *_p_i_d_P_t_r (in) ||
- Address of array containing |
- _n_u_m_P_i_d_s process ids. |
-
- int *_s_t_a_t_u_s_P_t_r (out) ||
- Address of place to store |
- status returned by |
- exited/suspended process. |
- _________________________________________________________________ |
-
-
- DDEESSCCRRIIPPTTIIOONN |
- These procedures keep track of child processes in order to |
- make it easier for one application to manage several chil- |
- dren. If an application uses the UNIX _f_o_r_k and _w_a_i_t kernel |
- calls directly, problems occur in situations like the fol- |
- lowing: |
-
- [1] ||
- One part of an application creates child C1. It plans |
- to let the child run in background, then later wait for |
- it to complete. |
-
- [2] ||
- Some other part of the application creates another |
- child C2, not knowing anything about C1. |
-
- [3] ||
-
-
-
- Sprite v1.0 1
-
-
-
-
-
-
- Tcl_Fork C Library Procedures Tcl_Fork
-
-
-
- The second part of the application uses _w_a_i_t to wait |
- for C2 to complete. |
-
- [4] ||
- C1 completes before C2, so C1 is returned by the _w_a_i_t |
- kernel call. |
-
- [5] ||
- The second part of the application doesn't recognize |
- C1, so it ignores it and calls _w_a_i_t again. This time |
- C2 completes. |
-
- [6] ||
- The first part of the application eventually decides to |
- wait for its child to complete. When it calls _w_a_i_t |
- there are no children left, so _w_a_i_t returns an error |
- and the application never gets to examine the exit |
- status for C1. |
-
- The procedures TTccll__FFoorrkk, TTccll__WWaaiittPPiiddss, and TTccll__DDeettaacchhPPiiddss |
- get around this problem by keeping a table of child |
- processes and their exit statuses. They also provide a more |
- flexible waiting mechanism than the _w_a_i_t kernel call. Tcl- |
- based applications should never call _f_o_r_k and _w_a_i_t directly; |
- they should use TTccll__FFoorrkk, TTccll__WWaaiittPPiiddss, and TTccll__DDeettaacchhPPiiddss. |
-
- TTccll__FFoorrkk calls _f_o_r_k and returns the result of the _f_o_r_k ker- |
- nel call. If the _f_o_r_k call was successful then TTccll__FFoorrkk |
- also enters the new process into its internal table of child |
- proceses. If _f_o_r_k returns an error then TTccll__FFoorrkk returns |
- that same error. |
-
- TTccll__WWaaiittPPiiddss calls _w_a_i_t repeatedly until one of the |
- processes in the _p_i_d_P_t_r array has exited or been killed or |
- suspended by a signal. When this occurs, TTccll__WWaaiittPPiiddss |
- returns the process identifier for the process and stores |
- its wait status at *_s_t_a_t_u_s_P_t_r. If the process no longer |
- exists (it exited or was killed by a signal), then |
- TTccll__WWaaiittPPiiddss removes its entry from the internal process |
- table. If _w_a_i_t returns a process that isn't in the _p_i_d_P_t_r |
- array, TTccll__WWaaiittPPiiddss saves its wait status in the internal |
- process table and calls _w_a_i_t again. If one of the processes |
- in the _p_i_d_P_t_r array has already exited (or suspended or been |
- killed) when TTccll__WWaaiittPPiiddss is called, that process and its |
- wait status are returned immediately without calling _w_a_i_t. |
-
- TTccll__WWaaiittPPiiddss provides two advantages. First, it allows |
- processes to exit in any order, and saves their wait sta- |
- tuses. Second, it allows waiting on a number of processes |
- simultaneously, returning when any of the processes is |
- returned by _w_a_i_t. |
-
-
-
-
- Sprite v1.0 2
-
-
-
-
-
-
- Tcl_Fork C Library Procedures Tcl_Fork
-
-
-
- TTccll__DDeettaacchhPPiiddss is used to indicate that the application no |
- longer cares about the processes given by the _p_i_d_P_t_r array |
- and will never use TTccll__WWaaiittPPiiddss to wait for them. This |
- occurs, for example, if one or more children are to be exe- |
- cuted in background and the parent doesn't care whether they |
- complete successfully. When TTccll__DDeettaacchhPPiiddss is called, the |
- internal process table entries for the processes are marked |
- so that the entries will be removed as soon as the processes |
- exit or are killed. |
-
- If none of the pids passed to TTccll__WWaaiittPPiiddss exists in the |
- internal process table, then -1 is returned and _e_r_r_n_o is set |
- to ECHILD. If a _w_a_i_t kernel call returns an error, then |
- TTccll__WWaaiittPPiiddss returns that same error. If a _w_a_i_t kernel call |
- returns a process that isn't in the internal process table, |
- TTccll__WWaaiittPPiiddss panics and aborts the application. If this |
- situation occurs, it means that a process has been created |
- without calling TTccll__FFoorrkk and that its exit status is about |
- to be lost. |
-
- TTccll__WWaaiittPPiiddss defines wait statuses to have type _i_n_t, which |
- is correct for POSIX and many variants of UNIX. Some BSD- |
- based UNIX systems still use type _u_n_i_o_n _w_a_i_t for wait sta- |
- tuses; it should be safe to cast a pointer to a _u_n_i_o_n _w_a_i_t |
- structure to (_i_n_t *) before passing it to TTccll__WWaaiittPPiiddss as in |
- the following code: |
-
- uunniioonn wwaaiitt ssttaattuuss;; |
- iinntt ppiidd11,, ppiidd22;; |
- ...... |
- ppiidd22 == TTccll__WWaaiittPPiiddss((11,, &&ppiidd11,, ((iinntt **)) &&ssttaattuuss));; |
-
-
- KKEEYYWWOORRDDSS |
- background, child, detach, fork, process, status, wait
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sprite v1.0 3
-
-
-
-